﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using wt.wine.Application.Common.Interfaces;
using wt.wine.Application.Common.Models;
using wt.wine.Application.ManageUserTable;
using wt.wine.Domain.Entities;

namespace wt.wine.Infrastructure.Persistence.Repository
{
    public class UsertableRepository : IUsertableRepository
    {
        private readonly IApplicationDbContext _dbcontext;
        public UsertableRepository(IApplicationDbContext dbContext)
        {
            _dbcontext = dbContext;
        }

        /// <summary>
        /// 通过账号、密码 登录
        /// </summary>
        /// <param name="account"></param>
        /// <param name="password"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task<usertable> Login(string account, string password, CancellationToken cancellationtoken)
        {
            return await _dbcontext.usertable.AsNoTracking().Where(p => p.account == account && p.password == password).FirstOrDefaultAsync(cancellationtoken);
        }

        public async Task<usertable> GetUpdateUserTableById(int id, int userid,CancellationToken cancellationtoken)
        {
            return await _dbcontext.usertable.AsNoTracking().Where(p => p.id == id && p.parentid == userid).FirstOrDefaultAsync(cancellationtoken);
        }

        /// <summary>
        /// 判断当前账号是否存在
        /// </summary>
        /// <param name="account"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task<int> GetAccountCount(int id ,string account, CancellationToken cancellationtoken)
        {
            return await _dbcontext.usertable.AsNoTracking().Where(p => p.id!= id && p.account == account && p.state >= 0).CountAsync(cancellationtoken);
        }

        /// <summary>
        /// 添加员工
        /// </summary>
        /// <param name="model"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task AddUserTable(usertable model, CancellationToken cancellationtoken)
        {
            await _dbcontext.usertable.AddAsync(model, cancellationtoken);
            await _dbcontext.SaveChangesAsync(cancellationtoken);
        }

        public async Task<GetUserTableByIdDTO> GetUserTableById(int id, int userid, CancellationToken cancellationtoken)
        {
            return await _dbcontext.usertable.AsNoTracking().Where(p => p.id == id && p.parentid == userid && p.state >= 0).Select(p => new GetUserTableByIdDTO
            {
                id = p.id,
                account = p.account,
                name = p.name,
                address = p.address,
                createtime = p.createtime,
                 type=_dbcontext.roletable.AsNoTracking().Where(x=>x.id==p.roleid &&x.state>=0).Select(p=>p.roletype??0).FirstOrDefault()
            }).FirstOrDefaultAsync(cancellationtoken);
        }


        public async Task<PaginatedList<GetUserTableByIdDTO>> GetUserList(int userid, int pageIndex, int pageSize, CancellationToken cancellationtoken)
        {
            var query = from u in _dbcontext.usertable.AsNoTracking().Where(p => (p.id == userid || p.parentid == userid) && p.state >= 0).OrderByDescending(p => p.id == userid ? 0 : 1).ThenByDescending(p => p.updatetime)
                        select new GetUserTableByIdDTO()
                        {
                            id = u.id,
                            account = u.account,
                            name = u.name,
                            address = u.address,
                            createtime = u.createtime,
                            type = _dbcontext.roletable.AsNoTracking().Where(p => p.id == u.roleid && p.state >= 0).Select(p => p.roletype ?? 0).FirstOrDefault()
                        };

            return await PaginatedList<GetUserTableByIdDTO>.CreateAsync(query, pageIndex, pageSize, cancellationtoken);
        }

        public async Task<int> GetLevel(int userid, CancellationToken cancellationtoken)
        {
            var model = await _dbcontext.usertable.AsNoTracking().Where(p => p.id == userid && p.state >= 0).FirstOrDefaultAsync(cancellationtoken);
            if (model != null && model.id > 0)
            {
                if (model.parentid == 0)
                {
                    return 1;
                }
                else
                {
                    var user = await _dbcontext.usertable.AsNoTracking().Where(p => p.id == model.parentid && p.state >= 0).FirstOrDefaultAsync(cancellationtoken);
                    if (user != null && user.id > 0 && user.parentid == 0)
                    {
                        return 2;
                    }
                    else
                    {
                        return 3;
                    }
                }
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 定时更新线路状态
        /// </summary>
        /// <param name="dt_now"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task EditDeviceTableList(DateTime dt_now, CancellationToken cancellationtoken)
        {
            var list = await _dbcontext.devicetable.AsNoTracking().Where(p => p.updatetime < dt_now && p.state > 1 && p.skuid > 0).ToListAsync(cancellationtoken);
            if (list != null && list.Any())
            {
                for (int i = 0; i < list.Count(); i++)
                {
                    list[i].state = 1;
                    list[i].updatetime = DateTime.Now;
                    _dbcontext.Entry<devicetable>(list[i]).Property("state").IsModified = true;
                    _dbcontext.Entry<devicetable>(list[i]).Property("updatetime").IsModified = true;
                }
                await _dbcontext.SaveChangesAsync(cancellationtoken);
            }
        }

        public async Task<int> GetUserTableIdByAccount(int parentid, string account, CancellationToken cancellationtoken)
        {
            return await _dbcontext.usertable.AsNoTracking().Where(p => p.account == account && p.parentid == parentid && p.state >= 0).Select(p => p.id).FirstOrDefaultAsync(cancellationtoken);
        }

        public async Task EditDeviceTable(usertable model, bool isUodatePwd, CancellationToken cancellationtoken)
        {
            _dbcontext.Entry<usertable>(model).Property("name").IsModified = true;
            _dbcontext.Entry<usertable>(model).Property("account").IsModified = true;
            _dbcontext.Entry<usertable>(model).Property("address").IsModified = true;
            _dbcontext.Entry<usertable>(model).Property("updatetime").IsModified = true;
            _dbcontext.Entry<usertable>(model).Property("userpid").IsModified = true;
            if (isUodatePwd)
            {
                _dbcontext.Entry<usertable>(model).Property("password").IsModified = true;
            }
            await _dbcontext.SaveChangesAsync(cancellationtoken);
        }
    }
}
